package edu.chalmers.AV_2DPlatformerFramework.Model;

import edu.chalmers.AV_2DPlatformerFramework.Model.GameModel;
import edu.chalmers.AV_2DPlatformerFramework.Control.MListener;
import edu.chalmers.AV_2DPlatformerFramework.Control.KBListener;
import java.util.ArrayList;
import javax.swing.JFrame;

/**
 * The main class for this framework. Extend this class to access basic functionality provided.
 * @version 0.3
 * @author Richard
 * @revised Andrea, 08-04-2014
 * @revised Andrea, 30-04-2014: Moved some logic to match a MVC pattern and edited methods accordingly.
 * @revised Andrea Buchholz & Richard Sundqvist: 080514
 */
public abstract class Game extends JFrame implements Runnable{
   
    private GameModel model;
    private final ArrayList<GameModel> modelList = new ArrayList();
    private final KBListener kbListener;
    private final MListener mListener;
    private final GameThread gameThread;

    /**
     * Creates a new Game instance with mouse/keyboard listeners and a tickrate of 10 ms.
     * @param width Width of the main game window.
     * @param height Height of the main game window.
     * @param title Game title.
     */
    public Game(int width, int height, String title){
        this.setSize(width, height);
        this.setFocusable(true);
        this.setTitle(title);
        this.setLocationRelativeTo(null); //Center the window
        this.setVisible(true);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
       
        gameThread = new GameThread(this, 10);
        mListener = new MListener(this);
        this.addMouseListener(mListener);
        kbListener = new KBListener(10);
        this.addKeyListener(kbListener);
    }
   
    @Override
    public void run(){
        //managePause(); //does not work
        if (model != null)
            model.run();
        this.repaint();
    }
   
    public void onCreate(){
    }
   
    public void onDestroy(){
    }  
   
    //Getters and setters
   
    /**
     * @param model
     */
    public void addModel(GameModel model){
        if (model == null){
            this.model = model;
        }
        modelList.add(model);
    }
   
    public void removeModel(GameModel model){
        modelList.remove(model);
    }
   
    public void restModelList(){
        modelList.clear();
    }
       
    public KBListener getKeyListener(){
        return kbListener;
    }
 
    public MListener getMouseListener(){
        return mListener;
    }
       
    /**
     * Sets the current model to the model at index i in modelList.
     * @param i
     */
    public void setCModel (int i){
        if (i >= modelList.size())
            throw new IllegalArgumentException("No such screen.");
        model = modelList.get(i);
    }  

    /**
     * Returns current model.
     * @return
     */
    public GameModel getCModel(){
        return model;
    }
   
    /**
     * Returns the list of all models
     * @return
     */
    public ArrayList<GameModel> getModelArray(){
        return modelList;
    }
   
    /**
     * Returns the current delay in the gameThread.
     * @return
     */
    public int getSleepDuration(){
        return gameThread.getDelay();
    }
   
    /**
     * Sets a delay to the gameThread.
     * @param duration
     */
    public void setSleepDuration(int duration){
        gameThread.setDelay(duration);
    }

    /**
     * @param model
     */
    public void setCModel(GameModel model) {
        if (model != null)
            this.model = model;
   }
}
